package com.cspg.ssss.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cspg.ssss.domain.*;
import com.cspg.ssss.repository.DfyyEntityMapper;
import com.cspg.ssss.repository.ProblemInstMapper;
import com.cspg.ssss.repository.ScoreAddApplyEntityMapper;
import com.cspg.ssss.util.DateUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class ProblemService {

    private static final Logger log = LoggerFactory.getLogger(ProblemService.class);

    @Autowired
    GradeRoleUserService gradeRoleUserService;
    @Autowired
    ProblemInstMapper problemInstMapper;

    @Autowired
    WxDepartmentService wxDepartmentService;

    @Autowired
    WxSendMsgService wxSendMsgService;

    @Autowired
    DfyyEntityMapper dfyyEntityMapper;

    @Autowired
    CheckItemService checkItemService;

    @Autowired
    CheckBatchService checkBatchService;

    @Autowired
    FeedbackService feedbackService;

    @Autowired
    ScoreAddApplyEntityMapper scoreAddApplyEntityMapper;

    @Transactional
    public int SycProblemFromSrc(){
        int r = problemInstMapper.insertFromSrc();
        List<ProblemInstCheckItemEntity> pclist = problemInstMapper.selectCheckItemWithProblem();
        if(pclist != null && pclist.size() > 0){
            for(int i=0;i<pclist.size();i++){
                JSONObject obj = new JSONObject();
                obj.put("id",pclist.get(i).getCid());
                obj.put("item",pclist.get(i).getItem());
                JSONObject checkitemObj = new JSONObject();
                checkitemObj.put("id","");
                checkitemObj.put("item","");

                JSONObject scoreitemObj = new JSONObject();
                scoreitemObj.put("id","");
                scoreitemObj.put("item","");

                checkitemObj.put("score_item",scoreitemObj);

                obj.put("content_item",checkitemObj);
                String check_item = obj.toJSONString();
                HashMap<String,Object> updatefiled = new HashMap<String,Object>();
                updatefiled.put("id",pclist.get(i).getId());
                updatefiled.put("check_item",check_item);
                problemInstMapper.updateProblemInst(updatefiled);
            }
        }

        return 0;
    }

    /**
     * 根据用户id返回打分问题列表
     * @param userid
     * @return
     */
    public List<ProblemInst> getProblemListByGradeUserAndStatusArray(String userid,List<Integer> status){
        List<String> departs = gradeRoleUserService.getGradeDepartsByUserid(userid);
        if(departs == null || departs.size() <=0){
            return null;
        }
        HashMap<String,Object> condition = new HashMap<String,Object>();
        condition.put("assessment_dept",departs);
        condition.put("problem_status_in",status);
        List<ProblemInst> retls = problemInstMapper.selectProblemInstList(condition);
        return retls;
    }

    /**
     * 根据用户id返回打分问题列表
     * @param userid
     * @return
     */
    public List<ProblemInst> getProblemListByGradeUser(String userid,int status){
        List<ProblemInst> retls = new ArrayList<ProblemInst>();
        List<String> departs = gradeRoleUserService.getGradeDepartsByUserid(userid);
        if(departs == null || departs.size() <=0){
            return retls;
        }
        HashMap<String,Object> condition = new HashMap<String,Object>();
        condition.put("assessment_dept",departs);
        condition.put("problem_status",status);
        retls = problemInstMapper.selectProblemInstList(condition);
        return retls;
    }

    /**
     * 根据用户id返回待打分审核列表
     * @param userid
     * @return
     */
    public List<ProblemInst> getProblemListByApproveAndStatus(String userid,int status){
        List<String> departs = gradeRoleUserService.getApproveDepartsByUserid(userid,0);
        List<ProblemInst> retls = new ArrayList<ProblemInst>();
        if(departs == null || departs.size() <=0){
            return retls;
        }
        HashMap<String,Object> condition = new HashMap<String,Object>();
        condition.put("assessment_dept",departs);
        condition.put("problem_status",status);
        retls = problemInstMapper.selectProblemInstList(condition);
        return retls;
    }

    /**
     * 根据用户id返回待反馈审核列表
     * @param userid
     * @return
     */
    public List<ProblemInst> getProblemListByFeebackApproveAndStatus(String userid,int status){
        List<String> departs = gradeRoleUserService.getApproveDepartsByUserid(userid,1);
        List<ProblemInst> retls = new ArrayList<ProblemInst>();
        if(departs == null || departs.size() <=0){
            return retls;
        }
        HashMap<String,Object> condition = new HashMap<String,Object>();
        condition.put("company",departs);
        condition.put("problem_status",status);
        retls = problemInstMapper.selectProblemInstList(condition);
        return retls;
    }

    /**
     * 根据被考核用户查询打分问题
     * @param userid
     * @param status
     * @return
     */
    public List<ProblemInst> getProblemListByViewerAndStatus(String userid,int status){
        List<ProblemInst> retls = new ArrayList<ProblemInst>();
        List<String> retDeparts = gradeRoleUserService.getApproveDepartsByUserid(userid,3);

        if(retDeparts == null || retDeparts.size() <=0){
            return retls;
        }

        HashMap<String,Object> condition = new HashMap<String,Object>();
        condition.put("company",retDeparts);
        condition.put("problem_status",status);
        retls = problemInstMapper.selectProblemInstList(condition);
        return retls;
    }

    public ProblemInst getProblemInstById(String id){
        HashMap<String,Object> condition = new HashMap<String,Object>();
        condition.put("id",id);

        List<ProblemInst> retls = problemInstMapper.selectProblemInstList(condition);
        if(retls.size() == 1){
            return retls.get(0);
        }

        return null;
    }

    public int updateProblemInst(Map<String,Object> updatefiled){

        return problemInstMapper.updateProblemInst(updatefiled);
    }


    /**
     * 根据打分问题的条件分页获取打分问题列表
     * @param pageNum
     * @param pageSize
     * @param condition
     * @return
     */
    public PageInfo<ProblemInst> getProblemListByPage(int pageNum, int pageSize,Map<String,Object> condition){
        PageHelper.startPage(pageNum, pageSize);
        List<ProblemInst> retlist = problemInstMapper.selectProblemInstListWithCondition(condition);

        PageInfo<ProblemInst> pgInfo = new PageInfo<ProblemInst>(retlist);
        return pgInfo;
    }

    public List<ProblemInst> getProblemListAllByCondition(Map<String,Object> condition){
        List<ProblemInst> retlist = problemInstMapper.selectProblemInstListWithCondition(condition);

        return retlist;
    }

    /**
     * 根据打分问题的审核人或复核人，选择打分问题列表
     * @param pageNum
     * @param pageSize
     * @param condition
     * @return
     */
    public PageInfo<ProblemInst> getProblemListWithApproveByPage(int pageNum, int pageSize,Map<String,Object> condition){
        PageHelper.startPage(pageNum, pageSize);
        List<ProblemInst> retlist = problemInstMapper.selectProblemInstListWithApproveUser(condition);

        PageInfo<ProblemInst> pgInfo = new PageInfo<ProblemInst>(retlist);
        return pgInfo;
    }

    public ProblemInst getProblemInstDetail(String id){
        Map<String,Object> condition = new HashMap<String,Object>();
        condition.put("id",id);
        List<ProblemInst> retlist = problemInstMapper.selectProblemInstListWithCondition(condition);
        if(retlist != null && retlist.size() == 1){
            return retlist.get(0);
        }
        return null;
    }

    private String getFullDepartPath(String strDept){
        return "超高压输电公司/" + strDept.replace("->","/");
    }

    public String SycProblemFromDyffAndDfyy_ch(){

        try {
            //所有考核载体
            List<CheckItem> checkItems = checkItemService.getCheckCategroy();
            //判断是否超出上传截止时间，超出不上传
            CheckBatchInst inst = checkBatchService.getCurrentCheckBachInst(0);
            if(inst != null) {
                JSONObject configObj = JSONObject.parseObject(inst.getConfig());
                int upload_days = configObj.getIntValue("upload_problem");
                int sync_problem_month = configObj.getIntValue("sync_problem_month");

                Date today = DateUtil.getCurrentDate();
                int period = DateUtil.workDaysPeriod(inst.getUpdate_time(),today);
                if(period <= upload_days) {
                    Date endDate = inst.getStart_date();
                    Calendar startC = Calendar.getInstance();
                    startC.setTime(endDate);
                    startC.add(Calendar.MONTH,sync_problem_month * -1);
                    Date startDate = startC.getTime();

                    Map<String,Object> condition = new HashMap<String, Object>();
                    condition.put("startDate",startDate);
                    condition.put("endDate",endDate);
                    List<DfyyEntity> type0Ls = dfyyEntityMapper.selectDfyyProblemlistType0WithPeriod(condition);
                    List<ProblemInst> type0Problems = new ArrayList<ProblemInst>();

                    for (int i = 0; i < type0Ls.size(); i++) {
                        ProblemInst tmpInst = convertToProblemInst(checkItems, type0Ls.get(i),inst);
                        problemInstMapper.insert(tmpInst);
                    }
                }
            }

            //判断是否超出上传截止时间，超出不上传
            CheckBatchInst inst1 = checkBatchService.getCurrentCheckBachInst(1);

            if(inst1 != null) {
                JSONObject configObj = JSONObject.parseObject(inst1.getConfig());
                int upload_days = configObj.getIntValue("upload_problem");
                int sync_problem_month = configObj.getIntValue("sync_problem_month");

                Date today = DateUtil.getCurrentDate();
                int period = DateUtil.workDaysPeriod(inst1.getUpdate_time(),today);
                if(period <= upload_days) {
                    Date endDate = inst.getStart_date();
                    Calendar startC = Calendar.getInstance();
                    startC.setTime(endDate);
                    startC.add(Calendar.MONTH,sync_problem_month * -1);
                    Date startDate = startC.getTime();

                    Map<String,Object> condition = new HashMap<String, Object>();
                    condition.put("startDate",startDate);
                    condition.put("endDate",endDate);
                    List<DfyyEntity> type1Ls = dfyyEntityMapper.selectDfyyProblemlistType1WithPeriod(condition);
                    List<ProblemInst> type1Problems = new ArrayList<ProblemInst>();

                    for (int i = 0; i < type1Ls.size(); i++) {
                        ProblemInst tmpInst = convertToProblemInst(checkItems, type1Ls.get(i),inst1);
                        problemInstMapper.insert(tmpInst);
                    }
                }
            }
        }catch (Exception ex){
            log.error("sync error : " + ex.getMessage());
            return "sync error : " + ex.getMessage();
        }

        return "";
    }

    private ProblemInst convertToProblemInst(List<CheckItem> checkItems,DfyyEntity en,CheckBatchInst inst){
        ProblemInst tmpInst = new ProblemInst();
        DfyyEntity tmpEn = en;
        tmpInst.setId(tmpEn.getId());
        tmpInst.setDepartment_path_name("");
        tmpInst.setProblem_type(inst.getCheck_type());
        tmpInst.setCpfs(tmpEn.getCpfs());
        tmpInst.setCompany(getFullDepartPath(tmpEn.getCompany()));
        tmpInst.setDept(getFullDepartPath(tmpEn.getDept()));
        tmpInst.setCategory(tmpEn.getCategory());
        tmpInst.setMatters(tmpEn.getMatters());
        tmpInst.setBatch_id(inst.getId());


        CheckItem itme = new CheckItem();
        itme.setId("0");
        itme.setItem(tmpEn.getMatters());
        for(int j=0;j<checkItems.size();j++){
            if(checkItems.get(j).getItem().equals(tmpEn.getMatters())){
                itme.setId(checkItems.get(j).getId());
                break;
            }
        }

        JSONObject obj = new JSONObject();
        obj.put("id",itme.getId());
        obj.put("item",itme.getItem());
        JSONObject checkitemObj = new JSONObject();
        checkitemObj.put("id","");
        checkitemObj.put("item","");

        checkitemObj.put("score_item",new JSONArray());

        obj.put("content_item",checkitemObj);
        String check_item = obj.toJSONString();

        tmpInst.setCheck_item(check_item);
        tmpInst.setDescription(tmpEn.getDescription());
        tmpInst.setRoot_cause(tmpEn.getRoot_cause());
        tmpInst.setOwnership(tmpEn.getOwnership());
        tmpInst.setRoot_cause_link(tmpEn.getWtgyhj());
        tmpInst.setSuggestions(tmpEn.getSuggestions());
        tmpInst.setCheck_time(tmpEn.getTime());
        tmpInst.setExpert(tmpEn.getExpert());
        tmpInst.setProblem_category4(tmpEn.getSlwt());
        tmpInst.setAssessment_dept(getFullDepartPath(tmpEn.getAssessment_dept()));
        tmpInst.setProblem_status(0);
        tmpInst.setInput_time(tmpEn.getCreatea_time());

        return tmpInst;
    }

    /**
     * 判断并切换打分的阶段
     * @return -1-未切换，0，1，2，3-已切换到的阶段状态
     */
    public int setNextStage(int check_type){
        CheckBatchInst inst = checkBatchService.getCurrentCheckBachInst(check_type);
        if(inst == null)
            return -1;

        JSONObject configObj = JSONObject.parseObject(inst.getConfig());
        int upload_days = configObj.getIntValue("upload_problem");
        int grade_days = configObj.getIntValue("grade");
        int feedback_days = configObj.getIntValue("feedback");
        int review_days = configObj.getIntValue("review");
        int add_score_apply_days = configObj.getIntValue("add_score_apply");
        int add_score_review_days = configObj.getIntValue("add_score_review");
        Date today = DateUtil.getCurrentDate();
        int period = DateUtil.workDaysPeriod(inst.getUpdate_time(),today);

        if(inst.getCurrent_stage() == 0){//切换到打分反馈阶段
            Map<String,Object> condition = new HashMap<String, Object>();
            condition.put("batch_id",inst.getId());
            condition.put("not_problem_status",2);
            List<ProblemInst> retls = problemInstMapper.selectProblemInstListWithCondition(condition);
/*            if(retls == null || retls.size() == 0){//全部打分审核完毕自动切换阶段
                inst.setCurrent_stage(1);
                inst.setUpdate_time(new Date());
                checkBatchService.updateCheckBatchInst(inst);
                log.info("switch to stage 1");
                return 1;
            }*/
            //根据限定期限，强制切换阶段
            if(period > (upload_days+grade_days)){
                //设置所有该批次问题状态为2，所有状态不为2的问题，扣分结果为0
                Map<String,Object> updatefiled = new HashMap<String, Object>();

                updatefiled.put("problem_status",2);
                updatefiled.put("score","0");
                for(int i=0;i<retls.size();i++){
                    updatefiled.put("id",retls.get(i).getId());
                    problemInstMapper.updateProblemInst(updatefiled);
                }

                //切换阶段
                inst.setCurrent_stage(1);
                inst.setUpdate_time(new Date());
                checkBatchService.updateCheckBatchInst(inst);
                log.info("到期强制切换 switch to stage 1");
                return 1;
            }

        }

        if(inst.getCurrent_stage() == 1){//切换到打分部门反馈审核阶段

            if(period > feedback_days){
                //对于没有审批完的，或者反馈拒绝后没修改完的，统统变为状态7，打分审核通过状态，即没有提交反馈，无异议
                Map<String,Object> condition = new HashMap<String, Object>();
                condition.put("batch_id",inst.getId());
                condition.put("not_problem_status",5);
                List<ProblemInst> retls = problemInstMapper.selectProblemInstListWithCondition(condition);

                Map<String,Object> updatefiled = new HashMap<String, Object>();
                updatefiled.put("problem_status",7);

                if(retls != null && retls.size() > 0) {
                    for (int i = 0; i < retls.size(); i++) {
                        updatefiled.put("id", retls.get(i).getId());
                        problemInstMapper.updateProblemInst(updatefiled);
                    }
                }


                //切换阶段
                inst.setCurrent_stage(2);
                inst.setUpdate_time(new Date());
                checkBatchService.updateCheckBatchInst(inst);
                log.info("switch to stage 2");
                return 2;
            }
        }

        if(inst.getCurrent_stage() == 2) {//切换到批次结束
//            if((retls == null || retls.size()==0) && (retsals == null || retsals.size()==0)){
//                //切换阶段
//                inst.setCurrent_stage(3);
//                inst.setUpdate_time(new Date());
//                checkBatchService.updateCheckBatchInst(inst);
//                log.info("switch to stage 3");
//                return 3;
//            }

            //到达期限处理
            if (period == (review_days+1)) {
                //未处理的反馈审核
                Map<String, Object> condition = new HashMap<String, Object>();
                condition.put("batch_id", inst.getId());
                condition.put("problem_status", 5);
                List<ProblemInst> retls = problemInstMapper.selectProblemInstListWithCondition(condition);

                Map<String, Object> updatefiled = new HashMap<String, Object>();
                updatefiled.put("problem_status", 7);

                if (retls != null && retls.size() > 0) {
                    for (int i = 0; i < retls.size(); i++) {
                        ProblemFeedbackEntity fbEn = feedbackService.getProblemFeedbackEntity(retls.get(i).getId());
                        fbEn.setFeedback_result(1);
                        feedbackService.updateProblemFeedback(fbEn);
                        updatefiled.put("id", retls.get(i).getId());
                        updatefiled.put("score", fbEn.getFeedback_score());
                        problemInstMapper.updateProblemInst(updatefiled);
                    }
                }


                //切换阶段
                //inst.setCurrent_stage(3);//此处不切换阶段，完成阶段在下一个批次开始时再切换
                //inst.setUpdate_time(new Date());
                //checkBatchService.updateCheckBatchInst(inst);
                log.info("到期强制切换 switch to stage 3");
                return 3;
            }
        }
            //加分申请单独处理
            {

                //加分申请处理，部门及单位审核未完成或不通过的，按未加分申请处理，最终审核未完成的，按通过处理
                //处理加分申请
                int period_addScore = DateUtil.workDaysPeriod(inst.getStart_date(),today);
                if(period_addScore > add_score_apply_days && period_addScore < add_score_apply_days + add_score_review_days) {
                    Map<String, Object> scoreAddCondition = new HashMap<String, Object>();
                    scoreAddCondition.put("batch_id", inst.getId());
                    int[] status_in = {0, 3, 4};
                    scoreAddCondition.put("apply_status_in", status_in);
                    List<ScoreAddApplyEntity> retsals = scoreAddApplyEntityMapper.selectScoreAddApply(scoreAddCondition);
                    if (retsals != null && retsals.size() > 0) {
                        for (int i = 0; i < retsals.size(); i++) {
                            ScoreAddApplyEntity t = retsals.get(i);
                            t.setApply_result(0);
                            t.setApply_status(5);
                            scoreAddApplyEntityMapper.updateScoreAddApply(t);
                        }
                    }
                }

                //未处理的加分申请
                int totle_period = add_score_apply_days + add_score_review_days;
                if(period_addScore > totle_period && period_addScore < totle_period + 2) {
                    Map<String, Object> scoreAddCondition2 = new HashMap<String, Object>();
                    scoreAddCondition2.put("batch_id", inst.getId());
                    scoreAddCondition2.put("apply_status", 1);
                    List<ScoreAddApplyEntity> retsals2 = scoreAddApplyEntityMapper.selectScoreAddApply(scoreAddCondition2);

                    //处理加分申请
                    if (retsals2 != null && retsals2.size() > 0) {
                        for (int i = 0; i < retsals2.size(); i++) {
                            ScoreAddApplyEntity t = retsals2.get(i);
                            t.setApply_result(1);
                            t.setApply_status(5);
                            scoreAddApplyEntityMapper.updateScoreAddApply(t);
                        }
                    }
                }
            }


        return -1;
    }

    /*
    统计相关服务
    * */

    /**
     * 根据条件统计某个状态的问题数量
     * @param condition
     * @return
     */
    public int getProblemCountByStatusWithCondition(Map<String,Object> condition){
        int cnt = problemInstMapper.selectProblemGradeNumStat(condition);
        return cnt;
    }

    /**
     * 根据条件统计各个状态的问题数量
     * @param condition
     * @return
     */
    public List<StatusCountEntity> getProblemStatusCountByWithCondition(Map<String,Object> condition){
        List<StatusCountEntity> statResult = problemInstMapper.selectProblemStatusNumStat(condition);
        return statResult;
    }

    /**
     * 公司对各单位评分情况统计，根据Company字段做统计
     * @param condition
     * @return
     */
    public List<GradeDeptStatEntity> getDeptGradeStatCompany(Map<String,Object> condition){
        List<GradeDeptStatEntity> retls = problemInstMapper.selectProblemStatusNumCompanyStat(condition);
        return retls;
    }

    /**
     * 公司对单位评分情况统计，根据Grade_Dept字段做统计，可以统计出科室的打分情况
     * @param condition
     * @return
     */
    public List<GradeDeptStatEntity> getDeptGradeStatSubDept(Map<String,Object> condition){
        List<GradeDeptStatEntity> retls = problemInstMapper.selectProblemGradeStatByGradeDept(condition);
        return retls;
    }

    /**
     * 单位对各部门评分情况统计，根据Dept字段做统计
     * @param condition
     * @return
     */
    public List<GradeDeptStatEntity> getDeptGradeStatDept(Map<String,Object> condition){
        List<GradeDeptStatEntity> retls = problemInstMapper.selectProblemStatusNumDeptStat(condition);
        return retls;
    }

    public void batchApproveProblem(Map<String,Object> condition){
        problemInstMapper.batchApproveProblem(condition);
    }

    /**
     * 打分审核时，统计各单位或者各部门被考核情况（被考核单位名称，待审核问题数，总扣分数）
     * @param condition
     * @return
     */
    public List<GradeDeptStatEntity> selectApproveProblemStatusNumStat(Map<String,Object> condition){
        return problemInstMapper.selectApproveProblemStatusNumStat(condition);
    }

}